package com.wolfpire.system.common.util;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.persistence.Transient;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.log4j.Logger;

import com.wolfpire.system.common.ReflectIgnore;

public class BeanUtils {
	
	private static final Logger logger = Logger.getLogger(BeanUtils.class);
	
	private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
	private static final DateFormat HOUR_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	private static final DateFormat TIME_FROMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	public static BeanUtilsBean beanUtilsBean;
	public static ConvertUtilsBean convertUtilsBean;
	
	static {
		convertUtilsBean = new ConvertUtilsBean();
		convertUtilsBean.register(new Converter(){

			@SuppressWarnings("rawtypes")
			public Object convert(Class arg0, Object arg1) {
				
				if (arg1 instanceof Date) {
					Date date = (Date) arg1;
					return date;
				} else {
					String p = (String)arg1;

					if(p== null || p.trim().length()==0){
						return null;
					}
					p = p.trim();
					try{
						if(p.length() == 10){
							return DATE_FORMAT.parse(p);
						}else if(p.length() == 16){
							return HOUR_FORMAT.parse(p);
						}else if(p.length() == 19){
							return TIME_FROMAT.parse(p);
						}else{
							return null;
						}
					}catch(Exception e){
						logger.error("把"+arg1+"转换成时间类型出错", e);
						return null;
					}
				}
				
				
			}
			
		}, Date.class);
		
		convertUtilsBean.register(new Converter() {
			
			@SuppressWarnings("rawtypes")
			@Override
			public Object convert(Class arg0, Object arg1) {
				
				BigDecimalConverter converter = new BigDecimalConverter();
				
				if(StringUtils.isNotBlank(arg1.toString())){
					return converter.convert(BigDecimal.class, arg1);
				}else{
					return new BigDecimal(0);
				}
				
			}
		}, BigDecimal.class);

		beanUtilsBean = new BeanUtilsBean(convertUtilsBean, new PropertyUtilsBean());
	}
	
	/*public static <M> void merge(M target, M destination) throws Exception {
        BeanInfo beanInfo = Introspector.getBeanInfo(target.getClass());
        
        // Iterate over all the attributes
        for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {

            // Only copy writable attributes
            if (descriptor.getWriteMethod() != null) {
                Object originalValue = descriptor.getReadMethod()
                        .invoke(target);
                // Only copy values values where the destination values is null
                if (originalValue == null) {
                    Object defaultValue = descriptor.getReadMethod().invoke(
                            destination);
                    descriptor.getWriteMethod().invoke(target, defaultValue);
                }

            }
        }
    }*/
	
	/**
	 * 对象合并
	 * 同属性，当orig不为null而dest为null进行复制
	 * @param dest	目标对象
	 * @param orig 源对象
	 * @throws Exception
	 */
	public static void mergeObject(Object dest, Object orig) throws Exception {
		if (null == dest) {
            throw new IllegalArgumentException ("No destination bean specified");
        }
        if (orig == null) {
            throw new IllegalArgumentException("No origin bean specified");
        }
        if (logger.isDebugEnabled()) {
        	logger.debug("BeanUtils.mergeObject(" + ToStringBuilder.reflectionToString(dest) + ", " + ToStringBuilder.reflectionToString(orig) + ")");
		} else if (logger.isInfoEnabled()) {
        	logger.info("BeanUtils.mergeObject(" + dest + ", " + orig + ")");
		}
        
        
        Field[] fields = orig.getClass().getDeclaredFields();
        for (Field field : fields) {
        	// 将字段注解为ReflectIgnore和Transient的排除在外
        	if (!field.isAnnotationPresent(ReflectIgnore.class)
        			&& !field.isAnnotationPresent(Transient.class)) {
        		String fieldName = field.getName();
            	Object value = ReflectionUtils.getFieldValue(orig, fieldName);
            	if (null != value) {
            		Object newValue = ReflectionUtils.getFieldValue(dest, fieldName);
            		if (null == newValue) {
            			ReflectionUtils.setFieldValue(dest, fieldName, value);
    				}
    			}
			}
		}
    }
	
}
